/**
 * @(#)RecursosHumanosManagerK.java Jan 24, 2007
 *
 * Copyright (c) 2005-2010 Psiqueware S.A. de C.V. All Rights Reserved.
 * This software is the proprietary information Psiqueware S.A. de C.V.
 * Use is subject to license terms.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * <br/>Usuario : Psique
 * <br/>Creaci&oacute;n: Jan 24, 2007 - 12:51:25 PM
 * <br/>
 * <br/>
 * <br/><t5>Cambios :</t5>
 * <br/><b>Fecha | Autor  |  Cambios</b>
 * <ul>
 * <li>Jan 24, 2007 | <a href = "mailto:AngelElectrico@PsiqueWare.com">Psique</a> | Creaci&oacute;n del Objeto.</li>
 *<li>Ene 25, 2007 | <a href = "mailto:AngelElectrico@PsiqueWare.com">Psique</a> | Se corrigi&oacute; el problema de la transaccionalidad rota con las excepciones de precondici&oacute;n.</li>
 * <li>Abr 19, 2007 | <a href = "mailto:AngelElectrico@PsiqueWare.com">Psique</a> | Se eliminar&oacute;n las referencias a las clases Empresa, Deportamento, etc y se cambiar&oacute;n por referencias a Estructura.</li>
 * </ul>
 */

package com.psiqueware.jazmin.empresas.recursos.humanos.manager;

import com.psiqueware.alheli.exception.NotNullConditionException;
import com.psiqueware.alheli.exception.NullArgumentException;
import com.psiqueware.alheli.dao.EnlaceTransaccional;
import com.psiqueware.alheli.logging.Logger;
import com.psiqueware.alheli.logging.LoggerFactory;
import com.psiqueware.alheli.manager.BaseManager;
import com.psiqueware.alheli.manager.ManagerException;
import com.psiqueware.alheli.seguridad.Llave;
import com.psiqueware.alheli.seguridad.Modulo;
import com.psiqueware.alheli.seguridad.ModulosManager;
import com.psiqueware.alheli.seguridad.SeguridadException;
import com.psiqueware.alheli.seguridad.SeguridadManagerFactory;
import com.psiqueware.alheli.seguridad.UsuarioSeguridad;

import com.psiqueware.jazmin.empresas.recursos.humanos.CategoriaEmpleo;
import com.psiqueware.jazmin.empresas.recursos.humanos.Contrato;
import com.psiqueware.jazmin.empresas.recursos.humanos.EstatusLaboral;
import com.psiqueware.jazmin.empresas.recursos.humanos.RazonSueldo;
import com.psiqueware.jazmin.empresas.recursos.humanos.RecursosHumanosManager;
import com.psiqueware.jazmin.empresas.recursos.humanos.TipoContrato;
import com.psiqueware.jazmin.empresas.recursos.humanos.TipoEmpleo;
import com.psiqueware.jazmin.empresas.recursos.humanos.dao.CategoriaEmpleoDAO;
import com.psiqueware.jazmin.empresas.recursos.humanos.dao.ContratoDAO;
import com.psiqueware.jazmin.empresas.recursos.humanos.dao.EstatusLaboralDAO;
import com.psiqueware.jazmin.empresas.recursos.humanos.dao.RazonSueldoDAO;
import com.psiqueware.jazmin.empresas.recursos.humanos.dao.RecursosHumanosDAOFactory;
import com.psiqueware.jazmin.empresas.recursos.humanos.dao.TipoContratoDAO;
import com.psiqueware.jazmin.empresas.recursos.humanos.dao.TipoEmpleoDAO;
import com.psiqueware.jazmin.empresas.recursos.humanos.modelo.CategoriaEmpleoK;
import com.psiqueware.jazmin.empresas.recursos.humanos.modelo.ContratoK;
import com.psiqueware.jazmin.empresas.recursos.humanos.modelo.EstatusLaboralK;
import com.psiqueware.jazmin.empresas.recursos.humanos.modelo.RazonSueldoK;
import com.psiqueware.jazmin.empresas.recursos.humanos.modelo.TipoContratoK;
import com.psiqueware.jazmin.empresas.recursos.humanos.modelo.TipoEmpleoK;
import com.psiqueware.manzanilla.informacion.documentos.Documento;
import com.psiqueware.manzanilla.informacion.documentos.DocumentosManager;
import com.psiqueware.manzanilla.informacion.documentos.DocumentosManagerFactory;
import com.psiqueware.tulipan.organizacional.Estructura;

import java.util.Date;
import java.util.List;


/**
 * Encargado de establecer la informaci&oacute;n de los posibles movimientos sobre los recursos humanos
 * de una Empresa.
 * <br/>Paquete Original: com.psiqueware.tulipan.empresas.manager
 * <br/>Nombre  Original: RecursosHumanosManagerK
 * <br/>Oprima para ver : <a href="RecursosHumanosManagerK.java.html"><i>C&oacute;digo Fuente</i> </a>
 *
 * @author <a href="mailto:AngelElectrico@PsiqueWare.com">Psique</a>
 * @version Revision: 1.1 Jan 24, 2007 12:51:25 PM
 * @noinspection DuplicateStringLiteralInspection,ClassWithoutToString,ReturnOfNull,MethodWithMultipleReturnPoints,OverlyCoupledClass
 */
public class RecursosHumanosManagerK extends BaseManager implements RecursosHumanosManager, Modulo
{

    /** Logger de clase para RecursosHumanosManagerK */
    private static final Logger s_log = LoggerFactory.getLogger ( RecursosHumanosManagerK.class );

    /** Manager para crear documentos. */
    private DocumentosManager m_documentosManager = DocumentosManagerFactory.getDocumentosManager ();


    /** DAO de {@link Contrato}. */
    private static ContratoDAO s_ContratoDAO = RecursosHumanosDAOFactory.findDAOContrato ();

    /** DAO de {@link RazonSueldo}. */
    private static RazonSueldoDAO s_RazonSueldoDAO = RecursosHumanosDAOFactory.findDAORazonSueldo ();

    /** DAO de {@link EstatusLaboral}. */
    private static EstatusLaboralDAO s_EstatusLaboralDAO = RecursosHumanosDAOFactory.findDAOEstatusLaboral ();

    /** DAO de {@link TipoContrato}. */
    private static TipoContratoDAO s_TipoContratoDAO = RecursosHumanosDAOFactory.findDAOTipoContrato ();

    /** DAO de {@link TipoEmpleo}. */
    private static TipoEmpleoDAO s_TipoEmpleoDAO = RecursosHumanosDAOFactory.findDAOTipoEmpleo ();

    /** DAO de {@link CategoriaEmpleo}. */
    private static CategoriaEmpleoDAO s_CategoriaEmpleoDAO = RecursosHumanosDAOFactory.findDAOCategoriaEmpleo ();

    /** {@link Llave} con la seguridad de este {@link Modulo}. */
    private Llave m_llave;

    /** Constructor de RecursosHumanosManagerK.
     * @noinspection ThisEscapedInObjectConstruction*/
    public RecursosHumanosManagerK ()
    {
        ModulosManager modulosManager = SeguridadManagerFactory.getModulosManager ();
        try
        {
            modulosManager.registrarModulo ( this );
        }
        catch ( SeguridadException e )
        {
            final String error = "<error><msg>No se pudo inicializar la seguridad de los Recursos Humanos</msg></error>";
            s_log.error ( error );
            s_log.error ( e );
            throw new RuntimeException ( error, e );
        }
    }


    /**
     * Crea un nuevo contrato para un {@link Empleado}.
     *
     * @param fechaIngreso        fecha de ingreso a la {@link Estructura}.
     * @param fechaBaja           fecha de baja a la {@link Estructura} si es para un {@link Contrato} temporal. Puede ser <code>null</code>.
     * @param tipoContrato        {@link TipoContrato} que se le dar&aacute; al trabajador.
     * @param tipoEmpleo          {@link TipoEmpleo} bajo el que trabajar&aacute;.
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     *
     * @return nuevo Contrato con su informaci&oacute;n seteado.
     *
     * @exception ManagerException en caso de no poder completar la operaci&oacute;n.
     */
    public Contrato nuevoContrato ( Date fechaIngreso, Date fechaBaja, TipoContrato tipoContrato, TipoEmpleo tipoEmpleo, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        ContratoK contratoK = null;
        try
        {

            //Validamos
            if ( null == tipoContrato ) throw new NullArgumentException( "<error>El argumento 'tipoContrato' no puede ser NULL.</error>" );
            if ( null == tipoContrato.getId () ) throw new IllegalArgumentException ( "<error>El argumento 'tipoContrato' deb&iacute;a encontrarse previamente persistido.</error>" );
            if ( null == tipoEmpleo ) throw new NullArgumentException ( "<error>El argumento 'tipoEmpleo' no puede ser NULL.</error>" );
            if ( null == tipoEmpleo.getId () ) throw new IllegalArgumentException ( "<error>El argumento 'tipoEmpleo' deb&iacute;a encontrarse previamente persistido.</error>" );
            if ( null == fechaIngreso ) throw new NullArgumentException ( "<error>El argumento 'fechaIngreso' no puede ser NULL.</error>" );
            //Creamos el Contrato
            contratoK = new ContratoK ( fechaIngreso, fechaBaja, tipoContrato, tipoEmpleo );

            s_ContratoDAO.saveContrato ( contratoK, enlaceTransaccional );
            return contratoK;
        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo persistir el Contrato.</msg><parametros>" + contratoK + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            enlaceTransaccional.rollBack ();
            throw new ManagerException ( error, e );
        }
    }


    /**
     * Realiza la descripci&oacute;n de este {@link Estatuslaboral} asign&aacute;ndole una clave y un {@link Documento} descriptivo.
     * En caso de que este objeto ya halla sido descrito una excepci&oacute;n saltar&aacute; dado que no se puede eliminar un documento asignado.
     * <br/>
     * En caso de no poder realizar la operacion porque el {@link UsuarioSeguridad} no tiene el {@link Permiso}
     * este metodo devolvera <code>null</code>.
     *
     * @param analista            {@link UsuarioSeguridad} que realiza la operacion.
     * @param estructura             a la que pertenece este {@link EstatusLaboral}.
     * @param clave               a asignar. No puede repetirse respecto a otra clave dada de alta previamente.
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     *
     * @return EstatusLaboral persistido.
     *
     * @exception com.psiqueware.alheli.manager.ManagerException
     *             en caso de no poder completar la operaci&oacute;n.
     * @noinspection CastToConcreteClass
     * @see com.psiqueware.manzanilla.informacion.documentos.DocumentosManager
     */
    public EstatusLaboral registrarEstatusLaboral ( UsuarioSeguridad analista, Estructura estructura, String clave, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        EstatusLaboralK oK = null;
        try
        {
            if ( m_llave.isHabilitadoActividad ( s_alterarCategoriasRecursosHumanos, analista ) )
            {
                //validamos
                if ( null == estructura ) throw new NullArgumentException ( "<error>El argumento 'estructura' no puede ser NULL.</error>" );
                if ( null == estructura.getId () ) throw new NullArgumentException ( "<error>El argumento 'estructura' deb&iacute;a encontrarse previamente persistido.</error>" );
                if ( null == clave ) throw new NullArgumentException ( "<error>El argumento 'clave' no puede ser NULL.</error>" );

                final Documento descripcion = m_documentosManager.nuevoDocumento ( enlaceTransaccional );
                oK = new EstatusLaboralK ( clave, descripcion, estructura.getId () );
                // validamos la clave.
                EstatusLaboral estatusAnterior = s_EstatusLaboralDAO.findEstatusLaboralPorClave ( clave, enlaceTransaccional );
                if ( null != estatusAnterior ) throw new NotNullConditionException ( "<error>El valor de 'estatusLaboralAnterior' deb&iacute;a ser NULL para que esta operaci&oacute;n se completar&aacute; correctamente.</error>" );
                //guardamos
                s_EstatusLaboralDAO.saveEstatusLaboral ( oK, enlaceTransaccional );
            }
            return oK;
        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo guardar la descripci&oacute;n del Estatuslaboral.</msg><parametros>" + oK + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            enlaceTransaccional.rollBack ();
            throw new ManagerException ( error, e );
        }

    }


    /**
     * Devuelve un listado de los {@link EstatusLaboral} que utiliza la {@link Estructura}.
     *
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     * @param estructura             cuya informaci&oacute;n se busca. Debe encontrarse persistida.
     *
     * @return una {@link List} con esos objetos; vac&iacute;a en caso de no encontrar ninguno.
     */
    public List<EstatusLaboral> listarEstatusLaboral ( Estructura estructura, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        try
        {
            return s_EstatusLaboralDAO.listEstatusLaboralPorEmpresa ( estructura, enlaceTransaccional );

        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo realizar el listado.</msg><parametros>" + estructura + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            throw new ManagerException ( error, e );
        }
    }


    /**
     * Realiza la descripci&oacute;n de este {@link RazonSueldo} asign&aacute;ndole una clave y un {@link Documento} descriptivo.
     * En caso de que este objeto ya halla sido descrito una excepci&oacute;n saltar&aacute; dado que no se puede eliminar un documento asignado.
     * <br/>
     * En caso de no poder realizar la operacion porque el {@link UsuarioSeguridad} no tiene el {@link Permiso}
     * este metodo devolvera <code>null</code>.
     *
     * @param analista            {@link UsuarioSeguridad} que realiza la operacion.
     * @param estructura             a la que pertenece este {@link RazonSueldo}.
     * @param clave               a asignar. No puede repetirse respecto a otra clave dada de alta previamente.
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     *
     * @return RazonSueldo persitida
     *
     * @exception com.psiqueware.alheli.manager.ManagerException
     *             en caso de no poder completar la operaci&oacute;n.
     * @noinspection CastToConcreteClass
     * @see com.psiqueware.manzanilla.informacion.documentos.DocumentosManager
     */
    public RazonSueldo registrarRazonSueldo ( UsuarioSeguridad analista, Estructura estructura, String clave, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        RazonSueldoK oK = null;
        try
        {
            if ( m_llave.isHabilitadoActividad ( s_alterarCategoriasRecursosHumanos, analista ) )
            {
                //validamos
                if ( null == estructura ) throw new NullArgumentException ( "<error>El argumento 'estructura' no puede ser NULL.</error>" );
                if ( null == estructura.getId () ) throw new NullArgumentException ( "<error>El argumento 'estructura' deb&iacute;a encontrarse previamente persistido.</error>" );
                if ( null == clave ) throw new NullArgumentException ( "<error>El argumento 'clave' no puede ser NULL.</error>" );
                final Documento descripcion = m_documentosManager.nuevoDocumento ( enlaceTransaccional );

                // validamos la clave.
                RazonSueldo razonSueldoAnterior = s_RazonSueldoDAO.findRazonSueldoPorClave ( clave, enlaceTransaccional );
                if ( null != razonSueldoAnterior ) throw new NotNullConditionException( "<error>El valor de 'razonSueldoAnterior' deb&iacute;a ser NULL para que esta operaci&oacute;n se completar&aacute; correctamente.</error>" );
                //creamos
                oK = new RazonSueldoK ( clave, descripcion, estructura.getId () );
                //guradmos
                s_RazonSueldoDAO.saveRazonSueldo ( oK, enlaceTransaccional );
            }
            return oK;
        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo guardar la descripci&oacute;n del RazonSueldo.</msg><parametros>" + oK + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            enlaceTransaccional.rollBack ();
            throw new ManagerException ( error, e );
        }
    }

    /**
     * Devuelve un listado de los {@link RazonSueldo} que utiliza la {@link Estructura}.
     *
     * @param estructura             cuya informaci&oacute;n se busca. Debe encontrarse persistida.
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     *
     * @return una {@link List} con esos objetos; vac&iacute;a en caso de no encontrar ninguno.
     */
    public List<RazonSueldo> listarRazonSueldo ( Estructura estructura, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        try
        {
            return s_RazonSueldoDAO.listRazonSueldoPorEmpresa ( estructura, enlaceTransaccional );

        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo realizar el listado.</msg><parametros>" + estructura + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            throw new ManagerException ( error, e );

        }
    }

    /**
     * Realiza la descripci&oacute;n de este {@link TipoContrato} asign&aacute;ndole una clave y un {@link Documento} descriptivo.
     * En caso de que este objeto ya halla sido descrito una excepci&oacute;n saltar&aacute; dado que no se puede eliminar un documento asignado.
     * <br/>
     * En caso de no poder realizar la operacion porque el {@link UsuarioSeguridad} no tiene el {@link Permiso}
     * este metodo devolvera <code>null</code>.
     *
     * @param analista            {@link UsuarioSeguridad} que realiza la operacion.
     * @param estructura             a la que pertenece este {@link TipoContrato}.
     * @param clave               a asignar. No puede repetirse respecto a otra clave dada de alta previamente.
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     *
     * @return TipoContrato persistido.
     *
     * @exception com.psiqueware.alheli.manager.ManagerException
     *             en caso de no poder completar la operaci&oacute;n.
     * @noinspection CastToConcreteClass
     * @see com.psiqueware.manzanilla.informacion.documentos.DocumentosManager
     */
    public TipoContrato registrarTipoContrato ( UsuarioSeguridad analista, Estructura estructura, String clave, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        TipoContratoK oK = null;
        try
        {
            if ( m_llave.isHabilitadoActividad ( s_alterarCategoriasRecursosHumanos, analista ) )
            {
                //validamos
                if ( null == estructura ) throw new NullArgumentException ( "<error>El argumento 'estructura' no puede ser NULL.</error>" );
                if ( null == estructura.getId () ) throw new NullArgumentException ( "<error>El argumento 'estructura' deb&iacute;a encontrarse previamente persistido.</error>" );
                if ( null == clave ) throw new NullArgumentException ( "<error>El argumento 'clave' no puede ser NULL.</error>" );
                final Documento descripcion = m_documentosManager.nuevoDocumento ( enlaceTransaccional );

                // validamos la clave.
                TipoContrato tipoContratoAnterior = s_TipoContratoDAO.findTipoContratoPorClave ( clave, enlaceTransaccional );
                if ( null != tipoContratoAnterior ) throw new NotNullConditionException ( "<error>El valor de 'tipoContratoAnterior' deb&iacute;a ser NULL para que esta operaci&oacute;n se completar&aacute; correctamente.</error>" );
                //guardamos
                oK = new TipoContratoK ( clave, descripcion, estructura.getId () );
                s_TipoContratoDAO.saveTipoContrato ( oK, enlaceTransaccional );
            }
            return oK;
        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo guardar la descripci&oacute;n del TipoContrato.</msg><parametros>" + oK + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            enlaceTransaccional.rollBack ();
            throw new ManagerException ( error, e );
        }

    }

    /**
     * Devuelve un listado de los {@link TipoContrato} que utiliza la {@link Estructura}.
     *
     * @param estructura             cuya informaci&oacute;n se busca. Debe encontrarse persistida.
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     *
     * @return una {@link List} con esos objetos; vac&iacute;a en caso de no encontrar ninguno.
     */
    public List<TipoContrato> listarTipoContrato ( Estructura estructura, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        try
        {
            return s_TipoContratoDAO.listTipoContratoPorEstructura ( estructura, enlaceTransaccional );
        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo realizar el listado.</msg><parametros>" + estructura + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            throw new ManagerException ( error, e );
        }
    }

    /**
     * Realiza la descripci&oacute;n de este {@link TipoEmpleo} asign&aacute;ndole una clave y un {@link Documento} descriptivo.
     * En caso de que este objeto ya halla sido descrito una excepci&oacute;n saltar&aacute; dado que no se puede eliminar un documento asignado.
     * <br/>
     * En caso de no poder realizar la operacion porque el {@link UsuarioSeguridad} no tiene el {@link Permiso}
     * este metodo devolvera <code>null</code>.
     *
     * @param analista            {@link UsuarioSeguridad} que realiza la operacion.
     * @param estructura             a la que pertenece este {@link TipoEmpleo}.
     * @param clave               a asignar. No puede repetirse respecto a otra clave dada de alta previamente.
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     *
     * @return TipoEmpleo persistido.
     *
     * @exception com.psiqueware.alheli.manager.ManagerException
     *             en caso de no poder completar la operaci&oacute;n.
     * @noinspection CastToConcreteClass
     * @see com.psiqueware.manzanilla.informacion.documentos.DocumentosManager
     */
    public TipoEmpleo registrarTipoEmpleo ( UsuarioSeguridad analista, Estructura estructura, String clave, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        TipoEmpleoK oK = null;
        try
        {
            if ( m_llave.isHabilitadoActividad ( s_alterarCategoriasRecursosHumanos, analista ) )
            {
                //validamos
                if ( null == estructura ) throw new NullArgumentException ( "<error>El argumento 'estructura' no puede ser NULL.</error>" );
                if ( null == estructura.getId () ) throw new NullArgumentException ( "<error>El argumento 'estructura' deb&iacute;a encontrarse previamente persistido.</error>" );
                if ( null == clave ) throw new NullArgumentException ( "<error>El argumento 'clave' no puede ser NULL.</error>" );
                final Documento descripcion = m_documentosManager.nuevoDocumento ( enlaceTransaccional );

                oK = new TipoEmpleoK ( clave, descripcion, estructura.getId () );

                // validamos la clave.
                TipoEmpleo tipoEmpleoAnterior = s_TipoEmpleoDAO.findTipoEmpleoPorClave ( clave, enlaceTransaccional );
                if ( null != tipoEmpleoAnterior ) throw new NotNullConditionException ( "<error>El valor de 'tipoEmpleoAnterior' deb&iacute;a ser NULL para que esta operaci&oacute;n se completar&aacute; correctamente.</error>" );

                s_TipoEmpleoDAO.saveTipoEmpleo ( oK, enlaceTransaccional );
            }
            return oK;
        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo guardar la descripci&oacute;n del TipoEmpleo.</msg><parametros>" + oK + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            enlaceTransaccional.rollBack ();
            throw new ManagerException ( error, e );
        }
    }


    /**
     * Devuelve un listado de los {@link TipoEmpleo} que utiliza la {@link Estructura}.
     *
     * @param estructura             cuya informaci&oacute;n se busca. Debe encontrarse persistida.
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     *
     * @return una {@link List} con esos objetos; vac&iacute;a en caso de no encontrar ninguno.
     */
    public List<TipoEmpleo> listarTipoEmpleo ( Estructura estructura, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        try
        {
            return s_TipoEmpleoDAO.listTipoEmpleoPorEstructura ( estructura, enlaceTransaccional );
        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo realizar el listado.</msg><parametros>" + estructura + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            enlaceTransaccional.rollBack ();
            throw new ManagerException ( error, e );
        }
    }

    /**
     * Realiza la descripci&oacute;n de este {@link CategoriaEmpleo} asign&aacute;ndole una clave y un {@link Documento} descriptivo.
     * En caso de que este objeto ya halla sido descrito una excepci&oacute;n saltar&aacute; dado que no se puede eliminar un documento asignado.
     * <br/>
     * En caso de no poder realizar la operacion porque el {@link UsuarioSeguridad} no tiene el {@link Permiso}
     * este metodo devolvera <code>null</code>.
     *
     * @param analista            {@link UsuarioSeguridad} que realiza la operacion.
     * @param estructura             a la que pertenece este {@link CategoriaEmpleo}.
     * @param clave               a asignar.  No puede repetirse respecto a otra clave dada de alta previamente.
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     *
     * @return CategoriaEmpleo persistido.
     *
     * @exception com.psiqueware.alheli.manager.ManagerException
     *             en caso de no poder completar la operaci&oacute;n.
     * @noinspection CastToConcreteClass
     * @see com.psiqueware.manzanilla.informacion.documentos.DocumentosManager
     */
    public CategoriaEmpleo registrarCategoriaEmpleo ( UsuarioSeguridad analista, Estructura estructura, String clave, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        CategoriaEmpleoK oK = null;
        try
        {
            if ( m_llave.isHabilitadoActividad ( s_alterarCategoriasRecursosHumanos, analista ) )
            {

                //validamos
                if ( null == estructura ) throw new NullArgumentException ( "<error>El argumento 'estructura' no puede ser NULL.</error>" );
                if ( null == estructura.getId () ) throw new NullArgumentException ( "<error>El argumento 'estructura' deb&iacute;a encontrarse previamente persistido.</error>" );
                if ( null == clave ) throw new NullArgumentException ( "<error>El argumento 'clave' no puede ser NULL.</error>" );
                final Documento descripcion = m_documentosManager.nuevoDocumento ( enlaceTransaccional );

                // validamos la clave.
                CategoriaEmpleo categoriaAnterior = s_CategoriaEmpleoDAO.findCategoriaEmpleoPorClave ( clave, enlaceTransaccional );
                if ( null != categoriaAnterior ) throw new NotNullConditionException ( "<error>El valor de 'categoriaEmpleoAnterior' deb&iacute;a ser NULL para que esta operaci&oacute;n se completar&aacute; correctamente.</error>" );
                //creamos
                oK = new CategoriaEmpleoK ( clave, descripcion, estructura.getId () );
                s_CategoriaEmpleoDAO.saveCategoriaEmpleo ( oK, enlaceTransaccional );
            }

        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo guardar la descripci&oacute;n del CategoriaEmpleo.</msg><parametros>" + oK + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            enlaceTransaccional.rollBack ();
            throw new ManagerException ( error, e );
        }
        return oK;
    }


    /**
     * Devuelve un listado de los {@link CategoriaEmpleo} que utiliza la {@link Estructura}.
     *
     * @param estructura             cuya informaci&oacute;n se busca. Debe encontrarse persistida.
     * @param enlaceTransaccional para asegurar la atomicidad de la transacci&oacute;n.
     *
     * @return una {@link List} con esos objetos; vac&iacute;a en caso de no encontrar ninguno.
     *
     * @exception com.psiqueware.alheli.manager.ManagerException
     *             en caso de no poder completar la operaci&oacute;n.
     */
    public List<CategoriaEmpleo> listarCategoriaEmpleo ( Estructura estructura, EnlaceTransaccional enlaceTransaccional ) throws ManagerException
    {
        try
        {
            return s_CategoriaEmpleoDAO.listCategoriaEmpleoPorEmpresa ( estructura, enlaceTransaccional );
        }
        catch ( Exception e )
        {
            String error = "<error><msg>No se pudo realizar el listado.</msg><parametros>" + estructura + "</parametros></error>";
            s_log.error ( error );
            s_log.error ( e );
            enlaceTransaccional.rollBack ();
            throw new ManagerException ( error, e );
        }
    }

    /**
     * Asigna la Llave a Modulo.
     * <p><b>Para uso exclusivo del componente se Seguridad.</b></p>
     *
     * @param llave a asignar.
     */
    public void setLlave ( Llave llave )
    {


        m_llave = llave;
    }

    /**
     * Devuelve la LlaveK del la clase.
     *
     * @return LlaveK.
     */
    public Llave getLlave ()
    {
        return m_llave;
    }
}

